

import sublime
import sublime_plugin
import sqlite3
# import requests
import urllib.request
import time
import uuid
import hashlib
import json


def get_errorcode_reson(errocode):
    error_code_to_reson_table = {
            '401':'账户已经欠费，请进行账户充值',
            '411':'访问频率受限,请稍后访问',
            '2412':'超过最大请求字符数',
            '-1':'无法访问网络',
            }
    return error_code_to_reson_table[errocode]


class NetworkException(RuntimeError):
    def __init__(self, *args: object) -> None:
        super().__init__(*args)
        self.args = args








class TranslateCommand(sublime_plugin.TextCommand):
    def __init__(self, view) -> None:
        self.view = view

        self.pos_word = "based on youdaoapi"
        self.explains = ''
        self.phonetic = '[None]'
        self.phonetic_am = '[None]'
        self.errocode = -1
        self.Html_content = '''
            <h5 class="">
                    <span class="keyword">{keyword}</span>
                    <div class="">
                        <span class="pronounce">英
                        <span class="phonetic">{phonetic}</span>
                        </span>
                        <span class="pronounce">美
                        <span class="phonetic">{phonetic_am}</span>
                        </span>
                    </div>
            </h5>
            <div class="trans-container">
                <ul>
                    {explains}
                </ul>
            </div>
        '''

    def run(self, edit):
        # 获取鼠标选中的第一个region的文字内容
        self.pos_word = self.view.substr(self.view.sel()[0])
        self.main()
        if self.errocode != '0':
            self.view.show_popup("<h4>{}</h4>".format(get_errorcode_reson(self.errocode)),
                    sublime.HIDE_ON_MOUSE_MOVE_AWAY, -1)

        else:
            self.view.show_popup(self.Html_content.format(
                keyword = self.pos_word,
                explains = self.explains,
                phonetic = self.phonetic,
                phonetic_am = self.phonetic_am
                ), 
                sublime.HIDE_ON_MOUSE_MOVE_AWAY, -1)
                  # on_navigate = None,
                  # on_hide = None)

    def main(self):
        self.search_on_web(self.pos_word)
        # ret = self.find_in_DB(self.pos_word)
        # if ret:
        #     self.phonetic = ret[1]
        #     self.phonetic_am = ret[2]
        #     self.explains = ret[3]
            
        # else:
            # self.search_on_web(self.pos_word)
            # self.Save_to_DB()


    def search_on_web(self, word):
        fy_service = youdaoapi()
        try:
            ret = fy_service.query(word)
        except Exception as e:
            self.pos_word = "Network Error!!!"
            print(e)
        else:
            ret = ret.decode("utf-8")
            ret  = json.loads(ret)
            self.pos_word = ret['query']
            self.errocode = ret['errorCode']
            self.phonetic = ret['basic']['us-phonetic']
            self.phonetic_am = ret['basic']['uk-phonetic']
            explains = ret['basic']['explains']
            for i in explains:
                self.explains = self.explains + '<li>{1}</li>'.format(i)





    def find_in_DB(self, word):
        DB_name = 'dict.db'
        conn = sqlite3.connect(DB_name)
        print("connect ok")
        try:
            if_first_create = '''
            create table if not exists sublime
            (source text,
            phonetic text
            phonetic_am text
            result text);
            '''

            conn.execute(if_first_create)
        except Exception as e:
            print("error when create table sublime:"+e.__str__())
            return False
        else:
            cursor = conn.cursor()

            sql = '''
                select * from sublime where source='%s'
                '''%(word)
            cursor.execute(sql)
            # the fetchone() -> a tuple(元组)
            if cursor.fetchone()[0]:
                return cursor.fetchone()
            else:
                return None
            

    def Save_to_DB(self):
        if self.errocode == 0:
            DB_name = 'dict.db'
            conn = sqlite3.connect(DB_name)
            try:
                cursor = conn.cursor()
                sql = '''
                insert into sublime values('%s', '%s', '%s', '%s');
                '''%(self.pos_word, self.phonetic, self.phonetic_am, self.explains)

                cursor.execute(sql)
                conn.commit()
                print("save word ok")

            except Exception as e:
                print(e)
                conn.rollback()

            finally:
                conn.close()





            
            
            

    
class youdaoapi():

    def __init__(self) -> None:
        self.url = 'https://openapi.youdao.com/api'
        # self.headers = {'Content-Type': 'application/x-www-form-urlencoded'}
        self.app_key = '552d0c75e3cd6ac3'
        self.app_secret = 'pDYwwZOupJNxEQIRWT9cYcg6xx0gp24z'

    def query(self, word):
        data = {}
        data['from'] = 'auto'
        data['to'] = 'auto'
        data['signType'] = 'v3'
        curtime = str(int(time.time()))
        data['curtime'] = curtime
        salt = str(uuid.uuid1())
        signStr = self.app_key + self.truncate(word) + salt + curtime + self.app_secret
        sign = self.encrypt(signStr)
        data['appKey'] = self.app_key
        data['q'] = word
        data['salt'] = salt
        data['sign'] = sign
        # data['vocabId'] = "您的用户词表ID" 
        data = json.dumps(data)

        # resonse = requests.post(self.url, data=data, headers=self.headers)
        resonse = ''
        req = urllib.request.Request(self.url, data=bytes(data.encode("utf-8")), method='POST')
        req.add_header('Content-Type', 'application/x-www-form-urlencoded')
        
        with urllib.request.urlopen(req) as resq:
            resonse = resq.read()

        return resonse


    def truncate(self, q):
        if q is None:
            return ''
        size = len(q)
        return q if size <= 20 else q[0:10] + str(size) + q[size - 10:size]

    def encrypt(self, signStr):
        hash_algorithm = hashlib.sha256()
        hash_algorithm.update(signStr.encode('utf-8'))
        return hash_algorithm.hexdigest()

